Ciarciaʼs Circuit Cellar
Byte Magazine, May 1984
Speed up your IBM PC with 16-bit co-processing power
Copyright © 1984 Steven A. Ciarcia. All rights reserved.
Steve Ciarcia
Consulting Editor
When asked what computer language I prefer, I generally reply, “Solder”. This response is not an effort to be cute but rather to express a preference for dealing in the terms I know best. I don't avoid software. I just try to minimize my involvement.
When it is necessary to write simulation and test programs, I bite the bullet. Unless the function is time-critical, I most often choose BASIC because it comes closest to being a universal programming language. Virtually all personal and business computers support it, and if I confine my command choices to the more common instructions, the demonstration programs that I compose on an IBM PC should also run on your Cromemco Z2.
Photo 1: The wire-wrapped prototype of the Trump Card, shown from the front. The left side of the board contains 512K bytes of type-4164 dynamic RAM; the right side contains the Zilog Z8001 and an interface to the IBM PC I/O-expansion bus.
With few exceptions, you can compute your accounts receivable or type in and play a game equally well with an Apple or IBM PC using BASIC. The fact that one has a 6502 microprocessor and the other uses an 8088 is irrelevant. The output will be the same. The value of high-level languages is that they isolate the user from microprocessor peculiarities and facilitate transportable software. Unfortunately, the average ROM (read-only memory)-resident BASIC interpreter was never written with performance in mind. Usually taking 5 to 10 milliseconds (ms) to execute an individual instruction, it can seem like forever when running long programs.
As a writer, I have grown to appreciate the universality of BASIC, even with its shortcomings. By treating the computer as a black box with I/O (input/output) ports and BASIC, I have been able to provide projects that can be implemented on most systems directly. As an engineer/designer, however, I am aggravated by its slowness and feel no animosity toward critics who have converted to languages such as Pascal or C to gain processing speed.
Rather than make further excuses, I decided to solve the problem in classic Circuit Cellar tradition— simply build a black box that improves system throughput and runs BASIC programs faster.
Photo 2: The rear of the Trump Card prototype. To save time, the memory section was laid out as a printed-circuit board, with wire-wrapping saved for the processor side. As shown here, the Trump Card is installed for testing in an MPX-16 computer, which has I/O slots compatible with the IBM PC.
Photo 3: Execution-time visual comparison. (3a) Without Trump Card—a two-second exposure of the display while running the BASICA program in listing 1. The program has executed the PRINT statement and still is dimensioning the arrays. (3b) With Trump Card—the same two-second exposure of the program execution (with PRINT statement added) shows the arrays have been dimensioned and the prime numbers are being overprinted so fast that they blur.
Generally speaking, most people confuse microprocessor benchmarks with system throughput. The comparison of microprocessor-instruction execution speeds is not really indicative of a computer's capabilities. Performance is more often governed by the operating system and magnitude of the application program. It is a false assumption that all software written for a 16-bit microprocessor will necessarily run faster than on an 8-bit microprocessor. Machine-language fast Fourier transforms (FFT) run quickly on a 6502, but an accounting package that has to constantly interleave a program into and out of disk may be encumbered by 64K bytes of operational memory in the Apple. In all likelihood, large spreadsheets and accounting programs will run more efficiently in the larger memory space provided on an 8088 system such as the IBM PC.
Raising the performance of a high-level language such as BASIC takes more than raising a microprocessor's clock rate. Instead, it involves a combination of decisions that can ultimately affect the entire system throughput. We can expand the memory available to application programs in an effort to limit repeated disk accesses and configure a portion of memory as a RAM (random-access read/write memory) disk drive to expedite disk operations when they are required. We can optimize the efficiency of the high-level language by operating it in a compiled mode rather than as a repeatedly interpreted task. Finally, if the functional throughput of a particular application becomes dependent upon direct microprocessor intervention, for those tasks, substitute a faster microprocessor or help it with a coprocessor.
Apple I Apple III TRS-80 Model II IBM PC IBM PC (with Trump Card) 224 222 189 190 2.4
Table 1: A comparison of execution times (in seconds) of the benchmark program in listing 1.
Listing 1: Sieve of Eratosthenes prime-number-generator program.
5 DEFINT A-Z 10 SIZE = 8190 20 DIM FLAGS(8191) 30 PRINT "Only 1 iteration " 50 COUNT = 0 60 FOR I = 0 TO SIZE 70 FLAGS(I) = 1 80 NEXT I 90 FOR I = 0 TO SIZE 100 IF FLAGS(I) = 0 THEN 180 110 PRIME = I+I +3 120 K = I + PRIME 130 IF K > SIZE THEN 170 140 FLAGS(K) = 0 150 K = K + PRIME 160 GOTO 130 170 COUNT = COUNT + 1 180 NEXT I 190 PRINT COUNT, " PRIMES"
This article is not about building a classic speed-up board for the IBM Pc. The word "speed-up" implies replacing the 8088 with an 8086 or 80186. Instead, visualize your PC as a black box with an input, output, and crank. Rather than simply turning the crank faster, think of adding another black box, in the same path between input and output, that performs selective tasks more efficiently and faster than the 8088 alone. To increase the relative throughput of the system, I have designated an alternate path for specific program functions.
I've named this separate box Trump Card. It is a functionally independent 10-MHz Zilog Z8001-based computer with its own 512K bytes of memory. Designed specifically as a compiled high-level-language computer, Trump Card is addressed as an I/O device that communicates through the expansion bus (see photos 1 and 2).
Among the specific functions that Trump Card supports are BASIC, C, CP/M-80, text editing, Z8000 assembly-language programming, and a RAM disk. It does not directly execute programs written in 8088 assembly code, such as Lotus 1-2-3. It instead executes programs written in high-level languages such as BASIC or C (a Pascal compiler and 8088-to-Z8000 translator are in the works). Alternatively, it can enhance the function of programs such as 1-2-3 by expanding available memory and speeding disk functions. The ultimate purpose of Trump Card is to improve system throughput.
This month, I will outline the basic functions of Trump Card and describe its hardware in detail. This is, of course, a Circuit Cellar construction project, and you are encouraged to build your own Trump Card. More on that later. Next month, I'll describe some of the software in detail and do a little benchmarking.
First, a little about Trump Card and the Z8001.
Trump Card is a peripheral board that plugs into any expansion slot on an IBM PC or PC-compatible computer. It contains a 10-MHz Z8001 and up to 512K bytes of memory. To use it, you simply load a BASIC, CP/M-80, or C program from PC-DOS and type "RUN:". Its memory can also be used as a RAM disk.
Trump Card comes with software that translates existing BASIC and other high-level-language programs to run with reduced overhead. To speed the execution of BASICA, Trump Card compiles the code with a special version of BASIC called TBASIC. Unlike other compilers, this has no separate compiled-code disk files (unless you specifically want them) and no long delays. TBASIC instantly compiles the program in a few tenths of a second when you load the file into Trump Card. In appearance, it looks like any old, slow interpreted BASIC, but it runs with the speed of a compiler.
TBASIC is PC BASICA-compatible. You can use either the Trump Card screen editor or BASICA's editor to write your programs. Then run the same program using either Trump Card or BASICA. Depending upon the instructions you use, Trump Card provides a tenfold to hundredfold increase in program performance (see photo 3). Table 1 shows typical results of what Trump Card can do with the prime-number Sieve of Eratosthenes program (September 1981 BYTE, page 180) frequently used to benchmark computer systems (see listing 1).
Though I conceived of Trump Card initially as a BASICA enhancement, it didn't take me long to realize that a Z8001 with 512K bytes of memory has some real computing power and deserves proper support. For that reason, the software supplied with this project is much more extensive than usual. With the utilities and languages included, you should have little trouble using the vast software base of Z80 and Z8000 programs.
Trump Card includes the following software:
BASIC Compiler — TBASIC is PC BASICA-compatible. The differences between the BASICA interpreter and the TBASIC compiler are minimal. Most instructions are implemented without modification.
CP/M-80 Emulator — Trump Card can run your CP/M-80 Z80 assembly-language programs directly without special disk headers or translation programs. Simply download your Z80 programs and run them.
C-Compiler — Trump Card includes the industry standard version of C that is described in The C Programming Language by Kernighan and Ritchie. Debugger—Intended to aid in program development. With it, you can examine and replace memory and register contents, set breakpoints, or single-step through programs.
Screen Editor — Incorporating many of the features included in word processors, the editor enables you to write or examine ASCII text files for either the PC or Trump Card's use.
Multilevel Language Compiler — This is a structured assembler that allows Pascal-like control and data types, arithmetic expressions with automatic or specified allocations of registers, and procedure calls with parameter passing.
RAM Disk — Trump Card can allocate 128K to 387K bytes of its on-board memory to function as an intelligent RAM disk (DOS 2.0 only). This memory is separate from and in addition to any already existing on the PC bus. Trump Card's other functions can run concurrently.
A block diagram of the Z8000's internal structure appears here as figure 1. As the programmer sees it, the Z8000 contains sixteen 16-bit general-purpose registers (for addresses or data) that may also be used in groups to form as many as eight 32-bit registers or four 64-bit registers. The low-order halves of the registers may be used for byte operations, thus the Z8000 is able to manipulate data in 8-, 16-, 32-, and 64-bit pieces.
The eight addressing modes are register, indirect-register, direct-address, indexed, immediate, base-address, base-indexed, and relative-address. The instruction set utilizes data types ranging from single bits to a 32-bit-long word. The processor executes 110 distinct instruction types that, when permuted by all the addressing modes and data types, create a set of more than 400 instructions.
The Z8000 has two different modes of operation: system and normal. Which mode of operation is in effect is controlled by a bit in the flag-and-control word (FCW). The main difference between the operating modes is that some of the control/interrupt and I/O instructions work only in the system mode. To simplify the design of the Trump Card, I chose to use only the system mode.
The Z8001 (see photo 4) is the memory-segmented version of Zilog's chip; it comes in a 48-pin DIP (dual-inline package), the pinouts of which are shown in figure 2. (The nonsegmented 40-pin version is called the Z8002.) By memory segmentation, the directly addressable 8-megabyte memory space is divided into as many as one hundred twenty-eight 64K-byte regions. Seven segment-selection lines coming out of the Z8001 control the high-order memory addressing. When the Z8001 is reset, the segment addressing automatically reverts to segment 0, the lowest 64K-byte block of memory. Transfer of control between segments is done by jumps, calls, and returns.
Figure 1: Block diagram of the internal structure of the Zilog Z8000 family of microprocessors.
Photo 4: The 48-pin dual-in-line package that houses the Zilog Z8001 microprocessor, the heart of the Trump Card.
Figure 2: Pinout arrangement of the Z8001 memory-segmented version.
The schematic diagram of figure 3 shows the Trump Card's circuitry. It can be plugged into any expansion slot of an IBM PC or into any other computer with compatible I/O slots and operating system.
Five of the Z8001's seven segment-selection lines, SN0 through SN4, are used in the Trump Card to decode addresses for up to 1 megabyte of RAM (512K bytes fit on the board) and 4K bytes of ROM (read-only memory). Segment line 4 selects be
tween the ROM, mapped into segments 0 through 15, and the RAM, residing in segments 16 through 31. The states of the segment lines are latched by IC3; segment line 4 is named RAM/
Address/Data Bus
The address/data lines coming from the Z8001 (AD0 through AD15) are a time-multiplexed address and data bus, which can address a range of 65,536 (64K) bytes of memory or a like number of I/O addresses. Since the Z8001 can form addresses at either word or byte boundaries, the least significant bit AD0 is used in byte operations to determine if the upper or lower byte is to be operated upon. The address on the AD lines becomes valid when the Z8001 asserts the
The latched addresses (LA0 through LA15) come out of the 74LS373s with LA0 combined with the signal B/
The Trump Card contains a pair of type-2716 EPROMs (erasable programmable read-only memories),
which contain a bootstrap loader for cold-start-up and
system-diagnostic routines. Address lines LA1 through LA11 are connected to the EPROMs, IC22 (even byte) and IC23 (odd byte). There is no need to use the
Figure 3: Schematic diagram of the Trump Card. Support is provided for 512K bytes of dynamic RAM in the form of type-4164 chips. If a 6-MHz Z8001A is used, the crystal frequency must be reduced to 12 MHz.
Number Type +5 V GND IC1 Z8001B 11 36 IC2 Z8581 5 14 IC3 74LS373 20 10 IC4 74S138 16 8 IC5 74LS373 20 10 IC6 74LS373 20 10 IC7 74ԼՏ04 14 7 IC8 74LSO8 14 7 IC9 74ԼՏ02 14 7 IC10 74ԼՏ08 14 7 IC11 74LS32 14 7 IC12 74LS04 14 7 IC13 74ԼՏ02 14 7 IC14 74LS138 16 8 IC15 74LS138 16 8 IC16 74LS138 16 8 IC17 74157 16 8 ΙC18 74157 16 8 IC19 74S74 14 7 IC20 74LSO8 14 7 IC21 2716 24 12 IC22 2716 24 12 IC23 74LS245 20 10 IC24 6116-3 24 12 IC25 74LS393 14 7 IC26 74LS245 20 10 IC27 74LS74 14 7 IC28 74LS133 16 8 IC29 74LSO4 14 7 IC30 74LS32 14 7 IC31 74LS51 14 7 IC32 74LS51 14 7 IC33 74LS00 14 7 IC34 74LS74 14 7 IC35 74LS74 14 7 IC36 4164-15 (150ns) 16 8 ... IC99 4164-15 (150ns) 16 8
Power wiring table for figure 3.
PC Address |
Trump Card Port |
Function |
03EE | 3 | A "write" to this port by the processor that has current use of the bucket will cause the 8-bit address counter IC25, to be reset to 0. It will also release the bucket for use by the other processor. If bit 0 of the data bus is set to a 0 when this write is performed by the 8088 processor, a nonmaskable interrupt (NMI) is also issued to the Z8001. Reading this port allows either processor to see data at the current address of the counter without incrementing the counter. If the bucket is not available, a read operation to this port will return an FF |
03EC | 1 | A read operation to this port by the processor that has the bucket reserved will return the data at the current address of the Counter and increment the Counter at the end of the read operation. A read by the processor that does not have the bucket will return a value of hexadecimal FF and will not increment the counter. A write to this port by the processor that has reserved the bucket will enter data at the current address of the Counter and increment the counter at the end of the operation. A write by the processor that does not have the bucket will not enter data and the counter will not be incremented. |
03E8 | x | This port is not used for data transfer by the Z8001. A write to this port by the 8088 will issue a reset to the Trump Card. |
Table 2: Communication between the Z8001 and the 8088 is through the “bucket”, a FIFO buffer made from a type-6116 static-memory chip and support components. Shown here are the three basic bucket functions and the addresses and codes for each.
Various status signals tell the rest of the system about the processor's condition and the type of information that is appearing on the address/data bus. The status signals are as follows:
Read/Write: The R/
Normal/
Byte/
Status Lines: Lines ST0 through ST3 are utilized to define the exact type of transaction occurring on the bus. Only 4 of the 16 possible codes are required for operation of the Trump Card. The first status code, 0000 (Internal Operation), is decoded but unused. The second operation code, 0001 (Memory Refresh), is output by the internal Z8001 memory-refresh timer and is used in refreshing the on-board dynamic RAM. (This signal is ANDed with MREQ and is used as one of the two select signals in the row-address-strobe generation logic.) The third operation, 0010 (Standard I/O Reference), is used in the process of communicating with the host 8088 processor. The fourth operation code, 0011 (Special I/O), denotes I/O associated with the signal !SPIO and is reserved for future expansion.
The basic clock rate for the Z8001 on the Trump Card is provided by IC2, a Zilog Z8581 clock generator and controller (CGC). The Z8001's clock-input maximum voltage must come within a certain range of the power-supply potential (precisely VCC - 0.4 V) and have a maximum rise and fall time of 10 nanoseconds (ns). Such requirements are difficult to meet with standard oscillators and TTL (transistor-transistor logic), but they are easily met by the CGC. The Z8581 also provides an easy and effective means of adjusting the processor's bus cycles to the speed of available memory devices.
The CGC is used on the Trump Card to stretch specific bus cycles. As used on the Trump Card, the Z8001 does three different basic categories of operations: internal operations, memory access, and input/output operations. The timing of the ZCLK signal emitted by the CGC depends on which of these bus activities is taking place. The Z8581 can be configured to add wait states that enable the use of 150- and 200-ns RAM chips.
Photo 5: A typical display on the Tektronix 1240 logic analyzer: the column-address-strobe/row-address-strobe timing of the Trump Card.
Photo 6: To aid in my initial development, a Zscan-8000 emulator is plugged by a ribbon cable into the Z8001 socket on the Trump Card. In emulation mode, the Zscan-8000 can run diagnostic programs and exercise all functions of the Trump Card at 4 MHz. Hardware debugging is greatly simplified because all sections of the hardware need not be working to use the emulator.
The “bucket” is the communications interface between the PC and Trump Card. This FIFO (first-in/first-out)-type dual-port memory configuration consists of a 6116 static memory (IC24), an 8-bit address counter (IC25), two data-bus buffers (ICs 23 and 26), and the necessary control logic to arbitrate access. Programs and instructions are passed between the two computers via this FIFO circuitry. As far as the PC is concerned, the bucket appears as two I/O port addresses. A system of soft ware handshaking between the computers determines which has reserved and is using the bucket. Table 2 shows the port addresses and their functions.
It is not possible for both processors to have use of the bucket at the same time. With the processors running asynchronously, arbitration is necessary. It is provided by four D-type flip-flops: two for access requests and two for access reservations. The two access-request flip-flops are clocked by the transition of an access-request signal from either processor (!IORQ for the Z8001 and !PCSEL for the 8088). The preset inputs of these flip-flops are connected to the !HOLD signal, which is active whenever one of the processors has succeeded in reserving the use of the bucket. When !HOLD is active, it prevents the other processor from gaining access.
The Z8001 communicates through the bucket for all its normal I/O by activating the IORQ line. The 8088 selects the bucket when it performs either an IOW (I/O write) or IOR (I/O read) in the range of the IBM's regular memory-address space from hexadecimal 03E8 to 03EE. Accesses to these addresses are decoded by IC28 to generate the Trump Card's !PCSEL signal.
The two access-reserve flip-flops sample the output of the request flipflops 180 degrees out of phase with each other. This is done to prohibit simultaneous requests from being honored. These flip-flops are cleared by a reset command issued from the reserving processor.
The Q outputs from these flip-flops are combined by a logical AND function with the processor request to form the active select states used by the bucket: !Z ANDed with
The
A nonmaskable interrupt to the Z8001 is generated when the 8088
TBASIC and C compilers and an assembler
BY STEVE CIARCIA
Copyright (c) 1984 Steven A. Ciarcia. All rights reserved.
Steve Ciarcia (pronounced "see-ARE-See-ah") is an electronics engineer and Computer consultant with experience in process control, digital design, nuclear instrumentation, and product development. In addition to writing for BYTE, he has published several books. He can be contacted at POB 582, Glastonbury, CT 06033.
Last month, we looked at the hardware of the Trump Card, a coprocessor board for use with the IBM Personal Computer (PC) or compatible computers. The presentation centered mainly on the Zilog Z8000's processor architecture, the support circuitry, and the interface between the Z8000 and the Intel 8088. But the power of the Trump Card can be unleashed only by the right Software. This month, I'll describe the collection of software I've assembled for the Trump Card from several sources—most of it designed to support further program development. Let's first quickly review the features of the Trump Card.
WHAT IS THE TRUMP CARD?
The Trump Card (see photo 1) is a printed-circuit board that plugs into any I/O (input/output) expansion slot of an IBM PC, an IBM PC XT or any computer compatible with them. It contains a Zilog Z8001 16-16-bit microprocessor (the memory-segmented version of the Z8000) running at 10 MHz and up to 512K bytes of RAM (random-access read/write memory). The Trump Card communicates with the PCs built-in 8088 processor through a 256-byte FIFO (first-in/first-out) buffer.
A variety of software is available for the Trump Card. The most important, from my point of view, is the language system for its special version of BASIC. As you would expect, the Trump Card's TBASIC compiler excels at making user programs run fast, but it's also so easy to use that it makes some interpreted versions of BASIC look clumsy. The source language accepted by the TBASIC compiler is nearly identical with that of the IBM PC's Advanced BASIC interpreter (BASICA) and includes a few enhancements, such as compilation of programs larger than 64K bytes.
Other software included with the Trump Card follows:
• CP/M-80 emulator. The Trump Card can run programs designed to run under Digital Research's CP/M-80 DOS (disk operating system) by emulating the 8-bit Z80 instruction set and DOS calls. No special file headers or instruction-translation programs are required.
• C compiler. The Source language accepted by this compiler follows that of Kernighan and Ritchie with a few minor differences (see reference 6).
• Screen editor. Incorporating many of the features normally found only in word-processing packages, the screen editor, called EE, enables you to write or examine ASCII (American National Standard Code for Information Interchange) text files for use either with the Trump Card or in the normal IBM PC environment.
• Y multilevel-language compiler. The unusual Ylanguage System is essentially a structured assembler that enables Pascal-like control constructs and data types, arithmetic expressions with automatic or specified allocations of registers, and procedure calls with parameter passing.
• Debugger. With the debugger, you can examine and replace the contents of memory and registers, set breakpoints, or single-step through programs. Intended to aid in program development, the debugger is an integral part of Y.
• Semiconductor disk emulator. Under versions of PC-DOS equal to or higher than 2.0, Trump Card can allocate 128K to 387K bytes of its On-board RAM to function as a RAM disk or disk emulator. This memory is separate from the memory already existing on the PC's motherboard or other expansion boards and resides in the Z8000's separate address space. The Trump Card can run another function concurrently with the disk emulator.
Photo 1: The soldered prototype printed-circuit version of Trump Card. RAM Sockets are at left, EPROMs are top center, and the Z8001 and support chips fill the remainder of the board.
TBASIC is a New version of the BASIC language that looks like an interpreter and executes like a compiler.
To initialize the Trump Card, run a program called LDZSYSCOM from PC-DOS. When it has completed setting up the Trump Card and installing the device driver needed by PC-DOS to communicate with it, LDZSYS returns control to PC-DOS and the host 8088 processor with the Z8000 awaiting further instructions. Example 1 in the text box on page 118 contains examples of this and other typical user commands (in italics) and the system's response (in roman type). The operation of the Trump Card is transparent to programs running on the host 8088. (If you think that you will always want the Trump Card's capabilities available, you can add a line containing LDZSYS to your PC-DOS AUTOEXEC.BAT file.)
To begin using the Trump Card, execute the "go" program, G.COM (G). When the Z8000 has control of the system, it returns with a colon prompt, as the fourth line of example I shows, indicating that the Z8000 is ready to accept commands. The text box also shows the command format for editing and compiling files and programs, which may be stored on the same disk used to boot PC-DOS.
As I said last month, a chief cause for my building the Trump Card was a feeling of frustration with the slowness of BASIC interpreters. had, of Course cOnsidered using an off-the-shelf BASIC compiler to speed up my programs, but I did not relish all the overhead operations required by the compilers I had seen, such as Microsoft's BASIC compiler.
The typical compiler requires three separate operations to run a BASIC program. First, the program source code must be written using an editor program. Next, the ASCII program text from the editor is compiled into object Code and stored in a disk file, which often takes several minutes. Finally, the Special BASIC run-time processor is loaded from the disk to supervise execution of the object program. At last, the program does its thing.
Interpreters, for all their inefficiency of execution, do have one important benefit; you quickly can add a line to your program and type RUN to see its effect. But if you want to change a line in a compiled program, it's back to the editor and all the way through the process again. So when you finally have your debugged, compiled program, it may indeed execute 100 times faster than under an interpreted one, but it may have taken you 10 times as long to get it running right. I think this is one reason BASIC compilers are not in wider use,
To counter this criticism, compiler manufacturers suggest developing code on an interpreted BASIC first and then compiling it. Such a suggestion, while valid, ignores the reason for a compiler in the first place. If a hundredfold increase in speed is necessary to achieve a program's objective, it hardly makes sense that to write and test the original program you must wait 100 times longer each time you must run it. The answer seemed relatively trivial to me—simply write a version of BASIC that looks like an interpreter and executes like a compiler. The result is TBASIC.
The Trump Card's TBASIC language system is a BASIC compiler that offers significantly faster execution of BASIC programs than does a BASIC interpreter, while furnishing an operating environment much like that of an interpreter TBASIC bridges the gap between traditional BASIC interpreters, which have built-in editors and are known for ease of use, and typical BASIC compilers, which produce rather efficient object code but can be difficult to work with, TBASIC's extremely fast compilation times and its capability for immediate-mode execution make Working with it as easy as working with a friendly but slow interpreted BASIC, but the resulting programs run with the speed of a compiler. Unlike other compilers, the object code is not written into a disk file before execution (unless you request it). Therefore, no long delays are needed. When you load the file into the Trump Card, TBASIC Compiles the program in a few tenths of a second.
Most programs that will run under the IBM PC's BASICA interpreter can be fed into TBASIC for compilation. You can use either the Trump Card's EE screen editor or the BASICA editor to write the programs. But if you then run the same program under both BASICA and TBASIC, depending upon the instructions you use, you will notice an increase in program performance by a factor of anywhere from 7 to 100. A listing of TBASIC's keywords is shown in table 1. TBASIC also supports most of BASICAS color and graphics commands (see photo 2).
Line numbers aren't required in the Source code of programs written for TBASIC except where a line is to be referenced elsewhere in the program; for example, the destination of a GOTO or GOSUB statement would need a line number. Although not requiring them, TBASIC certainly allows line numbers on every line, so existing BASICA source code will run under TBASIC, to the extent that the program is compatible with TBASICs syntax. Such programs can immediately benefit from the increase in performance provided by TBASIC.
The development of a program using a BASIC interpreter occurs in two modes: editing the program and running it. Developing a program with TBASIC involves three modes; editing, Compiling, and running. Obviously, the only difference is compilation, which is invoked on the Trump Card by the DO command; once the program has been compiled, the familiar RUN command executes it.
Example 2 on page 118 shows some examples of the kind of interaction that occurs when you use TBASIC; how to enter a program using the EE editor, compile it, and run the compiled program. In the text box, input by the user is shown in italic type while the system's prompts and output are shown in roman characters.
During compilation of a program, error messages are issued each time an error is encountered. The line of the Source file in which the error was detected is displayed; in some cases, an error message is also displayed. After an error is found and displayed, compilation continues and any other errors found also will be displayed. When the compilation has been completed, a list of any undefined symbols also may be output, in which case the program should not be run.
Photo 2: Color (2a) and graphics (2b) tests demonstrate TBASIC's support of color graphics commands normally associated with BASICA.
Three methods can be used for entering program Statements into the system for compilation under TBASIC. The first is to use the Trump Card's built-in EE screen editor, as mentioned previously (see photo 3). A second method is to enter the statements using TBASIC's direct-entry mode. The third choice is to enter and test the program using the computer's regular BASICA interpreter and then run it for effect using TBASIC. The three methods may be used interchangeably.
Photo 3: Programs in BASICA (3.a) and in C (36) can be written for Trump Card or the PC by using Trump Card's built-in EE editor.
Example 3 shows an example of these functions with a minimally modified version of the Sieve of Eratosthenes program often used as a system benchmark (see references 4 and 5). A program called SIEVES was previously written in BASICA and Stored as an ASCII file on the disk in drive B.
Suppose you want to run the program under both BASICA and TBASIC while recording how long it takes to be executed. You could use a stopwatch, but it's easier to add a few more program lines that record the starting and ending times automatically by calling the TIME$ function. It's possible to invoke the editor directly from TBASIC, as shown in example 3, to add two lines. And you can see that TBASIC took about 2 seconds to run the modified program as measured by the internal clock.
The program changes quickly were added and executed, and, when you left the editor with a QU command, the file SIEVES on drive B was updated to contain the TIMES-function Statements. After running the slightly revised program under BASICA, you see that it takes 202 seconds, around 100 times as long. Now consider the aggravation of making changes in programs that take this long to run and waiting for the results each time. Perhaps you now understand why I built the Trump Card. If you're interested in how fast some other computers and BASIC systems executed essentially the same program, see table 2. Another program that demonstrates how TBASIC speeds things up is the simple looping benchmark shown in listing 1. The results are shown in table 3.
TBASIC speeds up development and debugging as well as execution.
Not all programs run a hundred times faster in TBASIC. The Sieve program purposely uses integer arithmetic and avoids difficult floating-point calculations. But we can get an idea of floating-point performance from the simple benchmark routine of listing 2. In this program, TBASIC takes 3.2 seconds while BASICA takes 24.2.
This benchmark shows the wide variation in performance you can expect from a different mix of statements.
Of course, most other BASIC compilers for the IBM PC also can demonstrate dramatic speed increases over interpretive BASICA. But I believe that TBASIC is different because it speeds up development and debugging as well as execution.
(You might be wondering if the installation of an Intel 8087 Numeric Processor Extension in the IBM PC would help speed up execution of BASIC programs. Under BASICA, it would have no effect whatsoever because BASICA is not written to use it. I did a quick informal test using Morgan Professional BASIC, which uses the 8087, Morgan BASIC took 12.8 seconds to execute listing 2.)
TBASIC has many of the same convenience features for running programs that an interpreter has. You can use the commands RUN, RUN <line number>, GOTO <line number>, and GOSUB <line number> just as in BASICA. To stop a program from the console, you just hit Control-C. If possible, TBASIC will display the statement label nearest the point in the program where the stop occurred. Programs may contain STOP statements and may be restarted by a CONT command.
TBASIC also can execute statements and commands in immediate mode. You simply type the program line without a line number. (If you precede a statement with a line number, it will be compiled into the existing program.) You can get results like
-PRINT SQR(2) 1.414214 - -PRINT 2*3 6 -
You can print out variables or run specific program lines that contain line-identifier labels. Immediate-mode statements and commands also may be included in program files.
TBASIC also has some commands useful in debugging and problem diagnosis that you probably have not seen before. You can examine the actual compiled machine-language object code with commands like /DIAG. If you give the /DIAG command before a program is compiled, a complete list of compiler subroutine calls will be produced. This can be demonstrated in the direct-execution immediate mode, as shown in example 4 for both integer and floating-point values.
The Trump Card also supports a compiler for programs written in the C language.
For more ambitious program development, the Trump Card also supports a compiler for programs in the C language, as described by Kemighan and Ritchie (see reference 6). Programs need only slight modifications for compilation. Developing and running a C program is a three-step operation similar to the process used in TBASIC: editing, compiling, and running.
C compilers expect to find input and output routines in a subroutine library separate from the compiler. Kernighan and Ritchie describe a file called "stdio.h" that contains the I/O facilities.
The Trump Card's C compiler uses a file of I/O routines called "basicio.c", which includes the following routines: "getchar", "putchar", "open", "close", "read", "write", "printf", "scanf", "Iseek", and "creat".
The implementation of "scanf" and "printf" in the Trump Card's version of C differs slightly from that of Kernighan and Ritchie. In their implementation, the conversion characters "d" and "x" may each be preceded by an "1" to indicate a pointer to a "long" value rather than a pointer to an "int" value appears in the argument list. In this implementation, the uppercase conversion characters "D" and "X" are used for the same purpose. The conversion character "f" is used for floating point. The "scanf" routine assumes that the input values are separated by Space or Tab characters and that a Return character ends an input sequence.
The Trump Card's C compiler was designed with a user interface similar to that of TBASIC, and it's just as easy to use. Listing 3 shows a C program that is entered into the system using the EE editor in a manner such as that used for TBASIC. Example 5 shows how the program is compiled and run. Should you care to try the Sieve program in C, it is shown in listing 4 set up for 10 iterations. It runs in 3.2 seconds on the Trump Card, which compares quite favorably with versions of C running on 8-MHz MC68000 processors and with assembly-language versions on the IBM's 4.77-MHz 8088.
The Y language system compiles a multilevel language that can be best described as structured assembler code. It allows you to write programs using a mixture of Z8000 assembly language (in Zilog mnemonics), Pascal-like control structures, data types, arithmetic expressions with automatic or specified allocation of registers, procedure calls with parameter passing, and a descriptive compiler language. The different levels of constructs may. for the most part, be freely mixed.
The Y compiler generates code directly into memory with one pass and supports immediate execution of statements, conditional compilation, user-defined extensions to the language, and symbolic debugging. Most of the Z8000 mnemonics are implemented; those that are not can be used via the WORD pseudo-operation, as in the following:
LDCTL REFRESH, R3 = WORD 07D3B.
The TBASIC and C compilers are written in Y. Each of the compiler subroutines is a Y file that has been compiled into assembly-language code. A full explanation of Y is beyond the scope of this article, but listing 5 shows some Y code for your inspection. Y is an advanced tool for the experienced programmer.
The Trump Card supports a software emulator for CP/M-80 version 2.2, which allows the Trump Card to execute assembly-language programs for the 8-bit Z80 microprocessor.
The Z80 program must be transferred to a PC-DOS (or MS-DOS) floppy disk. (This can be done by linking a Z80-based computer and an IBM PC through a serial RS-232C connection, either through a direct cable or through a modem.) Once the Z80 program is on the IBM-format disk, its filename extension must be changed from "COM" to ".CMD", which is consistent with the CP/M-86 convention and avoids the problem of trying to run a Z80 program under IBM PC-DOS.
The emulator normally resides on a disk in drive B and is used in a manner very much like that of the other Trump Card software we've looked at. Nearly all the normal CP/M-80 system calls are supported by the emulator, with a few exceptions as shown in table 4. The standard CP/M-80 BIOS (basic input/output system) calls dealing with the disk, punch, and reader devices are not supported by the Z80 emulator; the remaining BIOS calls are supported.
The Trump Card is a board-level hardware approach to upgrading the performance of your IBM PC (or a compatible system). Aside from its function as a Z8000 development system, it provides many popular system enhancements in a single package: add-on memory, execution of Z80 programs, a separate editor, and language compilers. It was designed to solve my specific personal problem— I wanted a better BASIC that wasn't slow or cumbersome— and to support the PC in other ways: as a language and RAM-disk peripheral. If you're like me, these characteristics will be the most important ones to you.
In the process of building the Trump Card, however, I've found that it has potential I never imagined. Besides the software I've described, I expect that object-code translators for Z80-to-Z8000 and 8088-to-Z8000 conversions will soon be available, along with other utilities such as a print spooler. You also eventually will see Bell Laboratories' UNIX operating system for the Trump Card.
Next Month
Whimsy is in vogue, as Steve designs a musical telephone bell. ■
Z8000 and Z80 are trademarks of Zilog Corporation, a subsidiary of Exxon. CP/M-80 is a trademark of Digital Research.
To receive a complete list of Ciarcia's Circuit Cellar project kits available, circle 100 on the reader-service inquiry card at the back of the magazine.
EXAMPLE 1
Computer Interaction Comments A> LDZSYS Initialize Trump Card from PC-DOS. A> Control is returned to PC-DOS. A>G Turn control over to Trump Card. : (Trump Card's command prompt.) : : : EE <filename> Edit a file. : Z80EM <filename> Emulate Z80 and run CP/M-80 programs. : : C<filename> Compile and run a C program. : : Y<filename> Compile and run Z8000 structured assembly language. : : BASIC <filename> Compile and run TBASIC programs. : // Exit from Z8000 command interpreter. A> Control returns to PC-DOS.
Listing 1: A simple FOR. ..NEXT loop benchmark program in BASIC.
100 FOR A = 1 TO 10 115 FOR I = 1 TO 10 120 FOR T = TO 200 130 GOSUB 200 140 B = I 150 NEXT T 155 NEXT I 160 NEXT A 170 PRINT "DONE" 200 RETURN
Listing 2: A simple BASIC benchmark program for floating-point division.
60 A = 2.71828 80 B = 3.14159 100 FOR I = 1 TO 5000 120 C = A/B 320 NEXT I
Listing 3: A demonstration program for the C compiler.
main() { int count.step; count = 1: step = 1; while (count < = 5) { printf(" C language\n"); count = count + step; } }
Listing 4: The Sieve of Eratosthenes benchmark in C.
#define true 1 #define false 0 #define size 8190 #define sizepl 8191 char flags[sizepl]: main(){ register int i, prime, k, count, iter; printf( "10 iterations\n" ); for ( iter = 1; iter <= 10;iter++ ){ count =0: for( i = 0; i <= size; i++ ) flagslil = true; forli = 0;i <= size:i + + l{ if(flags[i]){ prime = i + i + 3; k = i + prime; while(k <= size){ flags[k] = false; k += prime; } count = count + I; } printf("\n%d primes ", count); } Listing 5: TBAS1C subroutines written on the Y multilevel-language compiler.[5a] if SWITCH = or CNT > 10O then begin SWITCH:=1; GODOITI2, VAL&0F) end else begin R3:="ABC; R5:= @R9|2|; R1:= CNT/2 LDIR @R3.@R5,R1 end [5b] COLOR: PROC ...passed flag, then other params depending on flag ...if flag bit 2 = 1, then set border color (if text model ...if bit 1 = 1, set background color (text) or palette (graphics) ...if bit 0= 1, set foreground color (text) or background color (graphics) save R6.R7 POPL RR6,@RRI2 if BIT R7,2 not zero then begin POPL RR2,@RR12 if SCRMODE <= I then SETBORDER(R3) end if BIT R7.I not zero then begin POPL RR2,0RRI2 if R0:= SCRMODE <= 1 then SETBGIR3) else if R0 = 2 then SETPALET(R3) end if BIT R7,0 not zero then begin POPL RR2,@RRI2 if R0:= SCRMODE <= 1 then SETFCIR3I else if R0=2 then SETGRAPHBGIR3I end restore R6,R7 RET SOUND: PROC ...passed duration (in 1/18.2 secs) and frequency ...make sound POPL RR4,@RRI2 ...duration POPL RR2,@RRI2 ...frequency EXB RL3.RH3: EXB RL5.RH5 R3:->BX; R5:->CX AH:= 4 ...sound EXTCALL(SPSCRINT) RET